{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Benchmark Round Trip time experiment (Switch)\n",
    "This notebook will show you how to measure the round trip time between two Alveo nodes using the benchmark application with UDP as a transport protocol.\n",
    "We are going to rely on a Dask cluster to configure the local and remote Alveo cards.\n",
    "\n",
    "This notebook assumes:\n",
    "* The Alveo cards are connected to a switch\n",
    "* Dask cluster is already created and running. For more information about setting up a Dask cluster visit the [Dask documentation](https://docs.dask.org/en/latest/setup.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style=\"border: 2px solid white;\">\n",
       "<tr>\n",
       "<td style=\"vertical-align: top; border: 0px solid white\">\n",
       "<h3 style=\"text-align: left;\">Client</h3>\n",
       "<ul style=\"text-align: left; list-style: none; margin: 0; padding: 0;\">\n",
       "  <li><b>Scheduler: </b>tcp://10.1.212.129:8786</li>\n",
       "  <li><b>Dashboard: </b><a href='http://10.1.212.129:8787/status' target='_blank'>http://10.1.212.129:8787/status</a>\n",
       "</ul>\n",
       "</td>\n",
       "<td style=\"vertical-align: top; border: 0px solid white\">\n",
       "<h3 style=\"text-align: left;\">Cluster</h3>\n",
       "<ul style=\"text-align: left; list-style:none; margin: 0; padding: 0;\">\n",
       "  <li><b>Workers: </b>2</li>\n",
       "  <li><b>Cores: </b>32</li>\n",
       "  <li><b>Memory: </b>232.35 GB</li>\n",
       "</ul>\n",
       "</td>\n",
       "</tr>\n",
       "</table>"
      ],
      "text/plain": [
       "<Client: 'tcp://10.1.212.129:8786' processes=2 threads=32, memory=232.35 GB>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from dask.distributed import Client\n",
    "\n",
    "client = Client(\"tcp://10.1.212.129:8786\")\n",
    "client"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "client_info = client.scheduler_info()['workers']\n",
    "workers = []\n",
    "for cli in client_info:\n",
    "    workers.append(client_info[cli]['name'])\n",
    "\n",
    "if len(workers) != 2:\n",
    "    print(\"Configure your Dask cluster with two workers\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basic remote functions\n",
    "In this part we are going to schedule a basic function to the workers to verify that we are able to pinpoint tasks to a particular worker, we are also going to grab the Alveo shell name.\n",
    "You should visually check that your xclbin file is built for the Alveo shell available on the workers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Worker name: alveo3c | shell version: \"xilinx_u280_xdma_201920_3\"\n",
      "Worker name: alveo4b | shell version: \"xilinx_u280_xdma_201920_3\"\n"
     ]
    }
   ],
   "source": [
    "import platform, os\n",
    "\n",
    "def verify_workers():\n",
    "    node_name = platform.node()\n",
    "    shell_version = os.popen(\"xbutil dump | grep dsa_name\").read()\n",
    "    #match = True\n",
    "    #if 'xilinx_u280_xdma_201920_3' not in shell_version:\n",
    "    #    match = False\n",
    "    return node_name, shell_version[24:-2]\n",
    "\n",
    "worker_0 = client.submit(verify_workers ,workers=workers[0], pure=False)\n",
    "worker_1 = client.submit(verify_workers ,workers=workers[1], pure=False)\n",
    "\n",
    "worker_check = [worker_0.result(),worker_1.result()]\n",
    "\n",
    "for w in worker_check:\n",
    "    print('Worker name: {} | shell version: {}'.format(w[0],w[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Source Dask device and utilities\n",
    "\n",
    "In this section we will import the libraries and dask on pynq class which allow us to:\n",
    "\n",
    "* Download a `xclbin` file to a worker\n",
    "* Peek and poke registers\n",
    "* Allocate buffers\n",
    "* Start kernels\n",
    "\n",
    "All of these capabilities are available for both local and remote workers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "\n",
       "try {\n",
       "require(['notebook/js/codecell'], function(codecell) {\n",
       "  codecell.CodeCell.options_default.highlight_modes[\n",
       "      'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n",
       "  Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n",
       "      Jupyter.notebook.get_cells().map(function(cell){\n",
       "          if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n",
       "  });\n",
       "});\n",
       "} catch (e) {};\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from vnx_utils import *\n",
    "import pynq\n",
    "%run dask_pynq.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Download xclbin to workers\n",
    "1. Create Dask device for each worker\n",
    "2. Create an overlay object for each worker, this step will download the `xclbin` file to the Alveo card"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/tools/external/anaconda/envs/pynq-dask/lib/python3.7/site-packages/distributed/worker.py:3321: UserWarning: Large object of size 60.94 MB detected in task graph: \n",
      "  (b'xclbin2\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff ... ROR_DATA_END',)\n",
      "Consider scattering large objects ahead of time\n",
      "with client.scatter to reduce scheduler burden and \n",
      "keep data on workers\n",
      "\n",
      "    future = client.submit(func, big_data)    # bad\n",
      "\n",
      "    big_future = client.scatter(big_data)     # good\n",
      "    future = client.submit(func, big_future)  # good\n",
      "  % (format_bytes(len(b)), s)\n"
     ]
    }
   ],
   "source": [
    "daskdev_w0 = DaskDevice(client, workers[0])\n",
    "daskdev_w1 = DaskDevice(client, workers[1])\n",
    "\n",
    "xclbin = '../benchmark.intf3.xilinx_u280_xdma_201920_3/vnx_benchmark_if3.xclbin'\n",
    "ol_w0 = pynq.Overlay(xclbin, device=daskdev_w0)\n",
    "ol_w1 = pynq.Overlay(xclbin, device=daskdev_w1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Check Link \n",
    "\n",
    "We are going to use the function `link_status` that reports if the CMAC is detecting link, which means that the physical connection\n",
    "between the two Alveo cards is established."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Link worker 0 {'cmac_link': True}; link worker 1 {'cmac_link': True}\n"
     ]
    }
   ],
   "source": [
    "print(\"Link worker 0 {}; link worker 1 {}\".format(ol_w0.cmac_0.link_status(),ol_w1.cmac_0.link_status()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Configure IP address of the Alveo cards\n",
    "In the next cell we are going to configure the IP address of the two Alveo cards"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Worker 0: {'HWaddr': '00:0a:35:02:9d:a5', 'inet addr': '10.1.212.165', 'gateway addr': '10.1.212.1', 'Mask': '255.255.255.0'}\n",
      "Worker 1: {'HWaddr': '00:0a:35:02:9d:a7', 'inet addr': '10.1.212.167', 'gateway addr': '10.1.212.1', 'Mask': '255.255.255.0'}\n"
     ]
    }
   ],
   "source": [
    "ip_w0 , ip_w1 = '10.1.212.165' , '10.1.212.167'\n",
    "if_status_w0 = ol_w0.networklayer_0.set_ip_address(ip_w0, debug=True)\n",
    "if_status_w1 = ol_w1.networklayer_0.set_ip_address(ip_w1, debug=True)\n",
    "print(\"Worker 0: {}\\nWorker 1: {}\".format(if_status_w0, if_status_w1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Configure remote Alveo card\n",
    "1. Set up connection table\n",
    "2. Launch ARP discovery\n",
    "3. Print out ARP Table "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Position   1\tMAC address 04:c5:a4:e3:fb:41\tIP address 10.1.212.1\n",
      "Position   4\tMAC address 52:54:00:90:c2:04\tIP address 10.1.212.4\n",
      "Position   6\tMAC address 52:54:00:90:c2:06\tIP address 10.1.212.6\n",
      "Position  11\tMAC address 00:1e:67:34:65:b8\tIP address 10.1.212.11\n",
      "Position  12\tMAC address 00:1e:67:34:63:b8\tIP address 10.1.212.12\n",
      "Position  13\tMAC address 00:1e:67:34:64:00\tIP address 10.1.212.13\n",
      "Position  14\tMAC address 00:1e:67:34:65:bc\tIP address 10.1.212.14\n",
      "Position  15\tMAC address 00:1e:67:34:64:20\tIP address 10.1.212.15\n",
      "Position  16\tMAC address 00:1e:67:34:64:08\tIP address 10.1.212.16\n",
      "Position  17\tMAC address 00:1e:67:34:65:18\tIP address 10.1.212.17\n",
      "Position  18\tMAC address 00:1e:67:34:65:28\tIP address 10.1.212.18\n",
      "Position  24\tMAC address 90:e2:ba:04:74:e0\tIP address 10.1.212.24\n",
      "Position  25\tMAC address 0c:42:a1:7c:c9:18\tIP address 10.1.212.25\n",
      "Position  33\tMAC address 90:e2:ba:55:df:65\tIP address 10.1.212.33\n",
      "Position  41\tMAC address 00:25:b5:00:00:1f\tIP address 10.1.212.41\n",
      "Position  42\tMAC address 00:25:b5:00:00:3f\tIP address 10.1.212.42\n",
      "Position  43\tMAC address 00:25:b5:00:00:3e\tIP address 10.1.212.43\n",
      "Position  44\tMAC address 00:25:b5:00:00:1e\tIP address 10.1.212.44\n",
      "Position  45\tMAC address 90:e2:ba:04:74:04\tIP address 10.1.212.45\n",
      "Position  46\tMAC address 90:e2:ba:46:e8:74\tIP address 10.1.212.46\n",
      "Position  47\tMAC address d4:ae:52:8c:80:79\tIP address 10.1.212.47\n",
      "Position  51\tMAC address 00:80:e5:19:37:71\tIP address 10.1.212.51\n",
      "Position  52\tMAC address 00:80:e5:19:35:b1\tIP address 10.1.212.52\n",
      "Position  61\tMAC address ec:f4:bb:bf:ec:90\tIP address 10.1.212.61\n",
      "Position  62\tMAC address b8:ca:3a:6f:6e:78\tIP address 10.1.212.62\n",
      "Position  63\tMAC address b8:ca:3a:6f:71:48\tIP address 10.1.212.63\n",
      "Position  64\tMAC address b8:ca:3a:6f:70:78\tIP address 10.1.212.64\n",
      "Position  71\tMAC address ec:f4:bb:db:aa:c0\tIP address 10.1.212.71\n",
      "Position  72\tMAC address ec:f4:bb:db:ba:48\tIP address 10.1.212.72\n",
      "Position  73\tMAC address ec:f4:bb:db:b8:98\tIP address 10.1.212.73\n",
      "Position  74\tMAC address ec:f4:bb:db:ab:f0\tIP address 10.1.212.74\n",
      "Position  75\tMAC address ec:f4:bb:db:ba:e8\tIP address 10.1.212.75\n",
      "Position  76\tMAC address ec:f4:bb:db:b9:38\tIP address 10.1.212.76\n",
      "Position  77\tMAC address ec:f4:bb:db:b1:48\tIP address 10.1.212.77\n",
      "Position  78\tMAC address ec:f4:bb:db:b1:b8\tIP address 10.1.212.78\n",
      "Position  79\tMAC address ec:f4:bb:db:b6:a0\tIP address 10.1.212.79\n",
      "Position  80\tMAC address ec:f4:bb:db:b1:c0\tIP address 10.1.212.80\n",
      "Position  81\tMAC address ec:f4:bb:db:b4:18\tIP address 10.1.212.81\n",
      "Position  82\tMAC address ec:f4:bb:db:b3:b8\tIP address 10.1.212.82\n",
      "Position 101\tMAC address 90:e2:ba:11:09:ac\tIP address 10.1.212.101\n",
      "Position 102\tMAC address 90:e2:ba:27:ff:a4\tIP address 10.1.212.102\n",
      "Position 103\tMAC address 24:6e:96:6a:f7:98\tIP address 10.1.212.103\n",
      "Position 104\tMAC address 24:6e:96:6a:f2:70\tIP address 10.1.212.104\n",
      "Position 110\tMAC address b8:59:9f:f6:7e:e8\tIP address 10.1.212.110\n",
      "Position 111\tMAC address e4:43:4b:aa:6a:30\tIP address 10.1.212.111\n",
      "Position 112\tMAC address e4:43:4b:8a:4d:d0\tIP address 10.1.212.112\n",
      "Position 113\tMAC address e4:43:4b:aa:65:d0\tIP address 10.1.212.113\n",
      "Position 114\tMAC address e4:43:4b:aa:66:10\tIP address 10.1.212.114\n",
      "Position 121\tMAC address b8:59:9f:f6:7f:40\tIP address 10.1.212.121\n",
      "Position 122\tMAC address b8:59:9f:f6:7f:60\tIP address 10.1.212.122\n",
      "Position 123\tMAC address b8:59:9f:f6:7f:70\tIP address 10.1.212.123\n",
      "Position 124\tMAC address b8:59:9f:f6:7f:30\tIP address 10.1.212.124\n",
      "Position 125\tMAC address 52:54:00:77:77:3a\tIP address 10.1.212.125\n",
      "Position 126\tMAC address b8:59:9f:e8:94:9a\tIP address 10.1.212.126\n",
      "Position 127\tMAC address b8:59:9f:e8:98:76\tIP address 10.1.212.127\n",
      "Position 128\tMAC address 52:54:00:77:77:4a\tIP address 10.1.212.128\n",
      "Position 129\tMAC address b8:59:9f:e8:96:16\tIP address 10.1.212.129\n",
      "Position 130\tMAC address b8:59:9f:e8:94:46\tIP address 10.1.212.130\n",
      "Position 131\tMAC address 90:e2:ba:da:1e:e4\tIP address 10.1.212.131\n",
      "Position 132\tMAC address 90:e2:ba:da:14:34\tIP address 10.1.212.132\n",
      "Position 133\tMAC address 90:e2:ba:ef:eb:4c\tIP address 10.1.212.133\n",
      "Position 134\tMAC address 90:e2:ba:ed:4e:58\tIP address 10.1.212.134\n",
      "Position 135\tMAC address 90:e2:ba:ef:f0:3c\tIP address 10.1.212.135\n",
      "Position 136\tMAC address 90:e2:ba:ef:eb:b4\tIP address 10.1.212.136\n",
      "Position 137\tMAC address 90:e2:ba:ef:f2:10\tIP address 10.1.212.137\n",
      "Position 138\tMAC address 90:e2:ba:ef:fb:44\tIP address 10.1.212.138\n",
      "Position 139\tMAC address 90:e2:ba:ef:eb:cc\tIP address 10.1.212.139\n",
      "Position 140\tMAC address 90:e2:ba:ef:ec:c0\tIP address 10.1.212.140\n",
      "Position 141\tMAC address 90:e2:ba:ed:57:4c\tIP address 10.1.212.141\n",
      "Position 142\tMAC address 90:e2:ba:ef:fb:88\tIP address 10.1.212.142\n",
      "Position 143\tMAC address 90:e2:ba:ef:ec:60\tIP address 10.1.212.143\n",
      "Position 144\tMAC address 90:e2:ba:ef:fb:a0\tIP address 10.1.212.144\n",
      "Position 145\tMAC address 90:e2:ba:ef:fb:98\tIP address 10.1.212.145\n",
      "Position 146\tMAC address 90:e2:ba:ef:fb:b8\tIP address 10.1.212.146\n",
      "Position 147\tMAC address 90:e2:ba:ed:56:d8\tIP address 10.1.212.147\n",
      "Position 148\tMAC address 90:e2:ba:ef:ed:00\tIP address 10.1.212.148\n",
      "Position 149\tMAC address 90:e2:ba:ed:4e:60\tIP address 10.1.212.149\n",
      "Position 150\tMAC address 90:e2:ba:ef:eb:a0\tIP address 10.1.212.150\n",
      "Position 161\tMAC address b8:59:9f:f6:7f:40\tIP address 10.1.212.161\n",
      "Position 162\tMAC address b8:59:9f:f6:7f:60\tIP address 10.1.212.162\n",
      "Position 163\tMAC address b8:59:9f:f6:7f:70\tIP address 10.1.212.163\n",
      "Position 164\tMAC address b8:59:9f:f6:7f:30\tIP address 10.1.212.164\n",
      "Position 165\tMAC address 00:0a:35:02:9d:a5\tIP address 10.1.212.165\n",
      "Position 209\tMAC address 00:0a:35:02:9d:e5\tIP address 10.1.212.209\n",
      "Position 210\tMAC address 00:0a:35:02:9d:e6\tIP address 10.1.212.210\n",
      "Position 211\tMAC address 00:0a:35:02:9d:e7\tIP address 10.1.212.211\n",
      "Position 213\tMAC address 00:0a:35:02:9d:e5\tIP address 10.1.212.213\n",
      "Position 214\tMAC address 00:0a:35:02:9d:e6\tIP address 10.1.212.214\n"
     ]
    }
   ],
   "source": [
    "ol_w1.networklayer_0.sockets[0] = (ip_w0, 62177, 60512, True)\n",
    "ol_w1.networklayer_0.populate_socket_table()\n",
    "\n",
    "ol_w1.networklayer_0.arp_discovery()\n",
    "\n",
    "ol_w1.networklayer_0.get_arp_table()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Configure local Alveo\n",
    "\n",
    "1. Set up connection table\n",
    "2. Launch ARP discovery\n",
    "3. Print out ARP Table "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Position   1\tMAC address 04:c5:a4:e3:fb:41\tIP address 10.1.212.1\n",
      "Position   4\tMAC address 52:54:00:90:c2:04\tIP address 10.1.212.4\n",
      "Position   6\tMAC address 52:54:00:90:c2:06\tIP address 10.1.212.6\n",
      "Position  11\tMAC address 00:1e:67:34:65:b8\tIP address 10.1.212.11\n",
      "Position  12\tMAC address 00:1e:67:34:63:b8\tIP address 10.1.212.12\n",
      "Position  13\tMAC address 00:1e:67:34:64:00\tIP address 10.1.212.13\n",
      "Position  14\tMAC address 00:1e:67:34:65:bc\tIP address 10.1.212.14\n",
      "Position  15\tMAC address 00:1e:67:34:64:20\tIP address 10.1.212.15\n",
      "Position  16\tMAC address 00:1e:67:34:64:08\tIP address 10.1.212.16\n",
      "Position  17\tMAC address 00:1e:67:34:65:18\tIP address 10.1.212.17\n",
      "Position  18\tMAC address 00:1e:67:34:65:28\tIP address 10.1.212.18\n",
      "Position  24\tMAC address 90:e2:ba:04:74:e0\tIP address 10.1.212.24\n",
      "Position  25\tMAC address 0c:42:a1:7c:c9:18\tIP address 10.1.212.25\n",
      "Position  33\tMAC address 90:e2:ba:55:df:65\tIP address 10.1.212.33\n",
      "Position  41\tMAC address 00:25:b5:00:00:1f\tIP address 10.1.212.41\n",
      "Position  42\tMAC address 00:25:b5:00:00:3f\tIP address 10.1.212.42\n",
      "Position  43\tMAC address 00:25:b5:00:00:3e\tIP address 10.1.212.43\n",
      "Position  44\tMAC address 00:25:b5:00:00:1e\tIP address 10.1.212.44\n",
      "Position  45\tMAC address 90:e2:ba:04:74:04\tIP address 10.1.212.45\n",
      "Position  46\tMAC address 90:e2:ba:46:e8:74\tIP address 10.1.212.46\n",
      "Position  47\tMAC address d4:ae:52:8c:80:79\tIP address 10.1.212.47\n",
      "Position  51\tMAC address 00:80:e5:19:37:71\tIP address 10.1.212.51\n",
      "Position  52\tMAC address 00:80:e5:19:35:b1\tIP address 10.1.212.52\n",
      "Position  61\tMAC address ec:f4:bb:bf:ec:90\tIP address 10.1.212.61\n",
      "Position  62\tMAC address b8:ca:3a:6f:6e:78\tIP address 10.1.212.62\n",
      "Position  63\tMAC address b8:ca:3a:6f:71:48\tIP address 10.1.212.63\n",
      "Position  64\tMAC address b8:ca:3a:6f:70:78\tIP address 10.1.212.64\n",
      "Position  71\tMAC address ec:f4:bb:db:aa:c0\tIP address 10.1.212.71\n",
      "Position  72\tMAC address ec:f4:bb:db:ba:48\tIP address 10.1.212.72\n",
      "Position  73\tMAC address ec:f4:bb:db:b8:98\tIP address 10.1.212.73\n",
      "Position  74\tMAC address ec:f4:bb:db:ab:f0\tIP address 10.1.212.74\n",
      "Position  75\tMAC address ec:f4:bb:db:ba:e8\tIP address 10.1.212.75\n",
      "Position  76\tMAC address ec:f4:bb:db:b9:38\tIP address 10.1.212.76\n",
      "Position  77\tMAC address ec:f4:bb:db:b1:48\tIP address 10.1.212.77\n",
      "Position  78\tMAC address ec:f4:bb:db:b1:b8\tIP address 10.1.212.78\n",
      "Position  79\tMAC address ec:f4:bb:db:b6:a0\tIP address 10.1.212.79\n",
      "Position  80\tMAC address ec:f4:bb:db:b1:c0\tIP address 10.1.212.80\n",
      "Position  81\tMAC address ec:f4:bb:db:b4:18\tIP address 10.1.212.81\n",
      "Position  82\tMAC address ec:f4:bb:db:b3:b8\tIP address 10.1.212.82\n",
      "Position 101\tMAC address 90:e2:ba:11:09:ac\tIP address 10.1.212.101\n",
      "Position 102\tMAC address 90:e2:ba:27:ff:a4\tIP address 10.1.212.102\n",
      "Position 103\tMAC address 24:6e:96:6a:f7:98\tIP address 10.1.212.103\n",
      "Position 104\tMAC address 24:6e:96:6a:f2:70\tIP address 10.1.212.104\n",
      "Position 110\tMAC address b8:59:9f:f6:7e:e8\tIP address 10.1.212.110\n",
      "Position 111\tMAC address e4:43:4b:aa:6a:30\tIP address 10.1.212.111\n",
      "Position 112\tMAC address e4:43:4b:8a:4d:d0\tIP address 10.1.212.112\n",
      "Position 113\tMAC address e4:43:4b:aa:65:d0\tIP address 10.1.212.113\n",
      "Position 114\tMAC address e4:43:4b:aa:66:10\tIP address 10.1.212.114\n",
      "Position 121\tMAC address b8:59:9f:f6:7f:40\tIP address 10.1.212.121\n",
      "Position 122\tMAC address b8:59:9f:f6:7f:60\tIP address 10.1.212.122\n",
      "Position 123\tMAC address b8:59:9f:f6:7f:70\tIP address 10.1.212.123\n",
      "Position 124\tMAC address b8:59:9f:f6:7f:30\tIP address 10.1.212.124\n",
      "Position 125\tMAC address 52:54:00:77:77:3a\tIP address 10.1.212.125\n",
      "Position 126\tMAC address b8:59:9f:e8:94:9a\tIP address 10.1.212.126\n",
      "Position 127\tMAC address b8:59:9f:e8:98:76\tIP address 10.1.212.127\n",
      "Position 128\tMAC address 52:54:00:77:77:4a\tIP address 10.1.212.128\n",
      "Position 129\tMAC address b8:59:9f:e8:96:16\tIP address 10.1.212.129\n",
      "Position 130\tMAC address b8:59:9f:e8:94:46\tIP address 10.1.212.130\n",
      "Position 131\tMAC address 90:e2:ba:da:1e:e4\tIP address 10.1.212.131\n",
      "Position 132\tMAC address 90:e2:ba:da:14:34\tIP address 10.1.212.132\n",
      "Position 133\tMAC address 90:e2:ba:ef:eb:4c\tIP address 10.1.212.133\n",
      "Position 134\tMAC address 90:e2:ba:ed:4e:58\tIP address 10.1.212.134\n",
      "Position 135\tMAC address 90:e2:ba:ef:f0:3c\tIP address 10.1.212.135\n",
      "Position 136\tMAC address 90:e2:ba:ef:eb:b4\tIP address 10.1.212.136\n",
      "Position 137\tMAC address 90:e2:ba:ef:f2:10\tIP address 10.1.212.137\n",
      "Position 138\tMAC address 90:e2:ba:ef:fb:44\tIP address 10.1.212.138\n",
      "Position 139\tMAC address 90:e2:ba:ef:eb:cc\tIP address 10.1.212.139\n",
      "Position 140\tMAC address 90:e2:ba:ef:ec:c0\tIP address 10.1.212.140\n",
      "Position 141\tMAC address 90:e2:ba:ed:57:4c\tIP address 10.1.212.141\n",
      "Position 142\tMAC address 90:e2:ba:ef:fb:88\tIP address 10.1.212.142\n",
      "Position 143\tMAC address 90:e2:ba:ef:ec:60\tIP address 10.1.212.143\n",
      "Position 144\tMAC address 90:e2:ba:ef:fb:a0\tIP address 10.1.212.144\n",
      "Position 145\tMAC address 90:e2:ba:ef:fb:98\tIP address 10.1.212.145\n",
      "Position 146\tMAC address 90:e2:ba:ef:fb:b8\tIP address 10.1.212.146\n",
      "Position 147\tMAC address 90:e2:ba:ed:56:d8\tIP address 10.1.212.147\n",
      "Position 148\tMAC address 90:e2:ba:ef:ed:00\tIP address 10.1.212.148\n",
      "Position 149\tMAC address 90:e2:ba:ed:4e:60\tIP address 10.1.212.149\n",
      "Position 150\tMAC address 90:e2:ba:ef:eb:a0\tIP address 10.1.212.150\n",
      "Position 161\tMAC address b8:59:9f:f6:7f:40\tIP address 10.1.212.161\n",
      "Position 162\tMAC address b8:59:9f:f6:7f:60\tIP address 10.1.212.162\n",
      "Position 163\tMAC address b8:59:9f:f6:7f:70\tIP address 10.1.212.163\n",
      "Position 164\tMAC address b8:59:9f:f6:7f:30\tIP address 10.1.212.164\n",
      "Position 167\tMAC address 00:0a:35:02:9d:a7\tIP address 10.1.212.167\n",
      "Position 209\tMAC address 00:0a:35:02:9d:e5\tIP address 10.1.212.209\n",
      "Position 210\tMAC address 00:0a:35:02:9d:e6\tIP address 10.1.212.210\n",
      "Position 211\tMAC address 00:0a:35:02:9d:e7\tIP address 10.1.212.211\n",
      "Position 213\tMAC address 00:0a:35:02:9d:e5\tIP address 10.1.212.213\n",
      "Position 214\tMAC address 00:0a:35:02:9d:e6\tIP address 10.1.212.214\n"
     ]
    }
   ],
   "source": [
    "ol_w0.networklayer_0.sockets[2] = (ip_w1, 60512, 62177, True)\n",
    "ol_w0.networklayer_0.populate_socket_table()\n",
    "\n",
    "ol_w0.networklayer_0.arp_discovery()\n",
    "\n",
    "ol_w0.networklayer_0.get_arp_table()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Configure application\n",
    "\n",
    "* Configure remote benchmark `traffic_generator_0_0` application in `LOOPBACK` mode"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "ol_w1_tg = ol_w1.traffic_generator_0_0\n",
    "ol_w1_tg.start(TgMode.LOOPBACK, 0)# Use connection in position 0 to reflect"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Configure local benchmark application\n",
    "This part configures the collector, in particular\n",
    "* Allocate buffers\n",
    "* Start collector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "send_packets   = 2 ** 20\n",
    "shape          = (send_packets,1)\n",
    "rtt_cycles     = pynq.allocate(shape, dtype=np.uint32, target=ol_w0.HBM0)\n",
    "pkt            = pynq.allocate(1,     dtype=np.uint32, target=ol_w0.HBM0)\n",
    "\n",
    "collector_h = ol_w0.collector_0_2.start(rtt_cycles,pkt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "**This part configures the traffic generator** `traffic_generator_0_2`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "send_pkts = send_packets\n",
    "ol_w0_tg = ol_w0.traffic_generator_0_2\n",
    "ol_w0_tg.reset_stats()\n",
    "ol_w0.networklayer_0.reset_debug_stats()\n",
    "\n",
    "ol_w0_tg.start(TgMode.LATENCY, 2, send_pkts, 1, 50)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Read latency result\n",
    "* Call the dask method to synchronize the Alveo buffer with the dask buffer\n",
    "\n",
    "Note that this buffer contains the round trip time in clock cycles"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PynqBuffer([[829],\n",
       "            [828],\n",
       "            [831],\n",
       "            ...,\n",
       "            [826],\n",
       "            [825],\n",
       "            [824]], dtype=uint32)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rtt_cycles.sync_from_device()\n",
    "rtt_cycles"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Compute some statistics on the results\n",
    "1. Convert the rtt from cycles to microseconds, get clock frequency by querying `.clock_dict['clock0']['frequency']`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "freq = int(ol_w1.clock_dict['clock0']['frequency'])\n",
    "rtt_usec = np.array(shape, dtype=np.float)\n",
    "rtt_usec= rtt_cycles / freq  # convert to microseconds"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. Use `scipy` to compute statistical values\n",
    "    * Mean\n",
    "    * Standard deviation\n",
    "    * Mode"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Round trip time at application level using 1,048,576 packets\n",
      "\tmean    = 2.759 us\n",
      "\tstd_dev = 0.005336 us\n",
      "\tmode    = 2.760 us, which appears 256,675 times\n",
      "\tmax     = 2.823 us\n",
      "\tmin     = 2.737 us\n"
     ]
    }
   ],
   "source": [
    "from scipy import stats\n",
    "mean, std_dev, mode = np.mean(rtt_usec), np.std(rtt_usec), stats.mode(rtt_usec)\n",
    "print(\"Round trip time at application level using {:,} packets\".format(len(rtt_usec)))\n",
    "print(\"\\tmean    = {:.3f} us\\n\\tstd_dev = {:.6f} us\".format(mean,std_dev))\n",
    "print(\"\\tmode    = {:.3f} us, which appears {:,} times\".format(mode[0][0][0],mode[1][0][0]))\n",
    "print(\"\\tmax     = {:.3f} us\".format(np.max(rtt_usec)))\n",
    "print(\"\\tmin     = {:.3f} us\".format(np.min(rtt_usec)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot Box and whisker graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'whiskers': [<matplotlib.lines.Line2D at 0x7f320065b5d0>,\n",
       "  <matplotlib.lines.Line2D at 0x7f320065bb10>],\n",
       " 'caps': [<matplotlib.lines.Line2D at 0x7f320065b9d0>,\n",
       "  <matplotlib.lines.Line2D at 0x7f320065b310>],\n",
       " 'boxes': [<matplotlib.lines.Line2D at 0x7f3200609190>],\n",
       " 'medians': [<matplotlib.lines.Line2D at 0x7f32006091d0>],\n",
       " 'fliers': [<matplotlib.lines.Line2D at 0x7f32005fb850>],\n",
       " 'means': []}"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1296x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "red_square = dict(markerfacecolor='r', marker='s')\n",
    "fig, ax = plt.subplots()\n",
    "ax.set_title('RTT Box and whisker plot')\n",
    "ax.set_xlabel('Round Trip Time (microsecond)')\n",
    "ax.set_yticklabels([''])\n",
    "fig.set_size_inches(18, 2)\n",
    "ax.boxplot(rtt_usec, vert=False, flierprops=red_square)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Release Alveo cards\n",
    "* To release the alveo cards the pynq overlay is freed\n",
    "* Delete dask pynq-dask buffers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "del rtt_cycles\n",
    "del pkt\n",
    "pynq.Overlay.free(ol_w0)\n",
    "pynq.Overlay.free(ol_w1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "------------------------------------------\n",
    "Copyright (c) 2020-2021, Xilinx, Inc."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
